package controllers;

import controllers.Notifications;
import play.*;
import play.mvc.*;

import java.util.*;

import org.apache.commons.mail.EmailException;

import models.*;
import controllers.Notifications;

//Created By C2 , Author IK_Ibrahim Kessba
@With(Secure.class)
// this class is used for the login, Doaa El-Hawary
public class Topics extends Controller {

	public static void index(long entityId) {
		viewTopics(entityId);
	}

	/**
	 * calls show.html in Topics folder which renders based on the Topic id for
	 * instance a user would click on a link surrounded with <a
	 * href="@Topics.show(topic.id)"></a> the method then check a couple of
	 * things before rendering
	 * 
	 * @author Amr Draz
	 * @version 2011.05.02
	 * @category C4S14
	 * @param id
	 *            : id of the topic that is to be shown
	 * @return none
	 */

	public static void show(long id) {

		Topic topic = Topic.findById(id);

		System.out.println(topic.getContent());
		System.out.println(topic.getId());
		// System.out.println(topic.getInitiator().getfName());

		// / Draz's check for org privacy
		String username = Security.connected();
		User user = User.findByUsername(username);
		if (topic.getOrganization().isPrivate()
				&& !(topic.getOrganization().isMember(user)))
			render("errors/503.html");
		// end draz part

		render(topic, user);
	}

	/**
	 * Creates a topic if the user is permitted to create a Topic .
	 * 
	 * @author mohamed elshikh
	 * @version 2011.0424
	 * @category C2D8
	 * @params title: title of the topic,content: content of the topic,type: type of the topic,entityid: id of the entity that contains the topic
	 * @return True if the topic is created,otherwise false
	 */
	public static boolean createTopic(String title, String content,
			String Type, long entityId) {
		Eentity entity = Eentity.findById(entityId);
		User user = User.find("byUsername", Security.connected()).first();

		boolean flag2 = true;

		for (int i = 0; i < entity.getTopics().size(); i++) {

			Topic t = entity.getTopics().get(i);
			if (t.getTitle().equals(title)) {
				flag2 = false;
				break;
			}
		}

		Topic topic = new Topic(user, title, content, Type);
		topic.setEntity(entity);
		entity.addTopic(topic);
		entity.getOrganization().addTopic(topic);
		user.addTopic(topic);
		render(flag2);
		return true;

	}

	public static void creatingTopic(Eentity entity) {
		User user = User.find("byUsername", Security.connected()).first();
		boolean flag = false;

		if (entity.getOrganizers().contains(user))
			flag = true;
		long id = entity.id;
		render(flag, id);

	}

	/**
	 * Closes a topic if the user is permitted to close a Topic
	 * 
	 * @author mohamed elshikh
	 * @version 2011.0424
	 * @category C2D8
	 * @params topicid: id of the topic that should be closed
	 * @return void
	 * @throws EmailException
	 */
	public static void closeTopic(long topicid) throws EmailException {
		Topic t = Topic.findById(topicid);
		User user = User.find("byUsername", Security.connected()).first();
		boolean flag = true;
		boolean flag2 = false;
		if (t.getEntity().getOrganizers().contains(user)) {
			flag2 = true;
		}
		if (t.getStatus() == "closed") {
			flag = false;

		}
		if (flag == true && flag2 == true) {
			t.setStatus("Closed");
			int length = t.getFollowers().size();
			long[] toBeNotified = new long[length];
			for (int i = 0; i < t.getFollowers().size(); i++) {
				toBeNotified[i] = t.getFollowers().get(i).getId();
			}
			Notifications.notifyMany(user.getId(), toBeNotified,
					"Topic closed", "the topic" + t.getTitle()
							+ "has been closed");
		}

		render(flag, flag2, t);

	}

	public static void viewTopic(long topicid) {
		Topic t = Topic.findById(topicid);
		render(t);

	}

	public static void editingTopic(long topicid) {
		Topic t = Topic.findById(topicid);
		String title = t.getTitle();
		String content = t.getContent();
		User s = User.find("byUsername", Security.connected()).first();

		boolean flag2 = true;
		boolean flag3 = false;
		long j = t.id;
		if (Topic.findById(j) == null) {
			flag2 = false;
		} else {
			if (t.getEntity().getOrganizers().contains(s)
					|| t.getInitiator() == s) {
				flag3 = true;

			}
		}
		render(flag2, flag3);
	}

	/**
	 * edit a topic if the user is permitted to change the contents of a certain topic
	 * 
	 * @author mohamed elshikh
	 * @version 2011.0424
	 * @category C2D9
	 * @params topicid: id of the topic to be edited, title: new title of the topic, content: new content
	 * @return void
	 * @throws EmailException
	 */
	public static void editTopic(long topicid, String title, String content)
			throws EmailException {
		Topic t = Topic.findById(topicid);
		User s = User.find("byUsername", Security.connected()).first();

		t.setTitle(title);
		t.setContent(content);

		int length = t.getFollowers().size();
		long[] toBeNotified = new long[length];
		for (int i = 0; i < t.getFollowers().size(); i++) {
			toBeNotified[i] = t.getFollowers().get(i).getId();
		}
		Notifications.notifyMany(s.getId(), toBeNotified, "Topic edited",
				"the topic" + t.getTitle() + "has been edited");
	}

	public static void viewTopics(long entityid) {
		String username = Security.connected();
		User user = User.findByUsername(username);
		Eentity e = Eentity.findById(entityid);
		List<Topic> tee = e.getTopics();
		boolean flag = true;
		if (tee.size() == 0) {
			flag = false;
		}
		render(tee, e, flag, user);
	}

	/**
	 * creates relationship among Topics if the user is permitted to relate topics
	 * 
	 * @author mohamed elshikh
	 * @version 2011.0428
	 * @category C2S11
	 * @params topicid1; id of the first topic,topicid2: id of the second topic,name: name of the relation
	 * 
	 * @return true if the relationship is created ,otherwise false
	 * @throws EmailException
	 */
	public static boolean relateTopics(long topicid1, long topicid2, String name)
			throws EmailException {
		Topic t1 = Topic.findById(topicid1);
		Topic t2 = Topic.findById(topicid2);
		User u = User.find("byUsername", Security.connected()).first();
		boolean flag = true;
		boolean flag2 = false;
		LinkedList<User> both = t1.getFollowers();
		for (int i = 0; i < t2.getFollowers().size(); i++) {
			both.add(t2.getFollowers().get(i));
		}
		Relationship relation = new Relationship(name, t1, t2, true);
		for (int i = 0; i < t1.getRelations().size(); i++) {
			if (t1.getRelations().get(i).getName() == name
					&& t1.getRelations().get(i).getDestination() == t2) {
				flag = false;
				break;

			}
		}

		if (t1.getEntity().getOrganizers().contains(u)
				&& t2.getEntity().getOrganizers().contains(u) && flag == true) {
			flag2 = true;

			if (flag2 = true) {
				relation.save();

				t1.addrelationship(relation);
				t2.addrelationship(relation);
				int length = both.size();
				long[] toBeNotified = new long[length];
				for (int i = 0; i < both.size(); i++) {
					toBeNotified[i] = both.get(i).getId();
				}

				Notifications.notifyMany(u.getId(), toBeNotified,
						"Topic relations", "the topic" + t1.getTitle()
								+ "has been related to" + t2);

			}
		}
		render(flag, flag2);
		return true;
	}

	public void relatingTopics(long topicid) {
		Topic t = Topic.findById(topicid);
		Eentity e = t.getEntity();
		List<Topic> tee = e.getTopics();
		long l = t.id;

		render(tee, e, l);

	}

	public void relatingTopicsfinally(long topicid1, long topicid2) {

		render(topicid1, topicid2);
	}

	/**
	 * checks whether user can post a topic to entity where he must be an
	 * organizer and posts the topic if yes
	 * 
	 * @author Caroline Tawfik
	 * @version 2010.0429
	 * @category C3S2
	 * @parameter String title,String content,String type, long entityId : all
	 *            atributes of topic
	 * 
	 * @return boolean: whether topic was posted or not depending on whether he
	 *         is an organizer or not and whether there exists a another topic
	 *         with the same name or not
	 */

	public static boolean postTopic(String title, String content, String type,
			long entityId) {
		String username = session.get("username");
		User sender = (User) User.find("byUsername", username).fetch().get(0);
		// Date date = new Date();
		render(title, content, type, entityId);

		return createTopic(title, content, type, entityId);

	}

	/**
	 * accepts the topic request. it checks whether the receiverId is the same
	 * as the user logged in and wheher he's an organizer. and then creates and
	 * posts the topic
	 * 
	 * @author Caroline Tawfik
	 * @version 2010.0504
	 * @category C3S13
	 * @parameter RequestId: the request to be accepted. String title,type,long
	 *            entityId
	 * @return nothing
	 * @throws EmailException
	 */
	public static void acceptTopicRequest(long requestId, String title,
			String type, long entityId) throws EmailException {
		// User receiver = User.find("byId",request.getRecieverId()).first();
		Request request = Request.findById(requestId);
		User receiver = User.findById(request.getReciever().getId());
		// User sender = User.find("byId", request.getSenderId()).first();
		String username = session.get("username");
		User user = (User) User.find("byUsername", username).fetch().get(0);
		User sender = User.findById(request.getSender().getId());
		boolean flag = false;
		if (request.getType().contains("topic")) {
			if (receiver.getId() == user.getId()) {
				if (user.getRoleList().contains("Organizer")
						|| user.getRoleList().contains("Lead")) {
					request.setResponse("accepted");
					request.save();
					user.sendNotification(receiver,
							"Your Topic request has been accepted.",
							"Your topic request: \n " + request.toString()
									+ "\n has been accepted.");
					Eentity entity = Eentity.findById(entityId);
					flag = true;
					render(title, request.getContent(), type, entityId, flag);
					createTopic(title, request.getContent(), type, entityId);
					render(title, request.getContent(), type, entityId, flag);

				}
			}
		}
		render(title, request.getContent(), type, entityId, flag);
	}

	/**
	 * Returns all the tags that belongs to a certain Topic
	 * 
	 * @author Arwa Ismail
	 * @version 2010.05.05
	 * @category C4-dependency
	 * @params int topicID: ID of the topic requested to have its tags returned
	 * @return List: list of all tags in that topic
	 */

	public static List getAllTopicTags(int topicID) {
		Topic x = Topic.findById(topicID);
		return (x.getTags());

	}

	 /**
	 * if the topic is already spammed it notifies the user of that and if not it sends notification 
	 * 
	 * @author Nora zakhary
	 * @version 2011.0504
	 * @category C3S7
	 * @param long id
	 * @return void
	 */

	 public static void toSpamTopic(long id) throws EmailException{
	    	Topic t = Topic.findById(id);
	        boolean notSpammed;
	    	
	    	if(t.isSpam()){
	    		notSpammed=false;
	    	}
	    	else{
	    	t.setSpam(true);
	    	notSpammed= true;
	    	t.save();
	    	//Users.notifySpammedIdea(id);
	    	
	    	}
	     render(id,notSpammed);
	    }

	// author aly Mostafa*
	/**
	 * * closes a topic by choosing and idea from the topic to be executed
	 * 
	 * @author Aly Mostafa
	 * @version 2011.0506
	 * @category C3S6
	 * @params Takes topic id
	 * @return void
	 */

	public static void closeTopicAndPromoteExecution(long topicId) {
		String username = session.get("username");
		User user = (User) User.findByUsername(username);

		Topic t = Topic.findById(topicId);
		if (t.getInitiator() == user || t.getOrganization().getLead() == user) {
			List<Idea> list = t.getIdeas();
			render(topicId, list);
		} else {
			error("not authorized");

		}

	}

	/**
	 * * closes topic and promote execution
	 * 
	 * @author Aly Mostafa
	 * @version 2011.0506
	 * @category C3S6
	 * @params Takes topic id and idea to be promoted
	 * @return void
	 * @throws EmailException
	 */
	public static void finalizeCloseAndPromote(long topicId, long ideaId)
			throws EmailException {

		Topics.closeTopic(topicId);
		Ideas.promoteToExecution(ideaId);

		render();

	}

	
	public static void topicHome() {
		render();
	}
}
